package com.cxm.weilai.util;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileWriter;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamSource;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.DocumentResult;
import org.dom4j.io.DocumentSource;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;

/**
 * xml工具包
 *
 * @author admin
 */
public class XmlUtil {
    private static Log logger = LogFactory.getLog(XmlUtil.class);


    /**
     * 解析XML
     *
     * @return Map<String, String>
     */
    public static Map<String, String> parserXml(String xmlStr) {
        Map<String, String> map = new HashMap<String, String>();
        try {
            Document document = DocumentHelper.parseText(xmlStr);
            Element root = document.getRootElement();
            @SuppressWarnings("unchecked")
            Iterator<Element> it = root.elementIterator();
            while (it.hasNext()) {
                Element element = it.next();
                @SuppressWarnings("unchecked")
                Iterator<Element> eleIt = element.elementIterator();
                while (eleIt.hasNext()) {
                    Element ele = eleIt.next();
                    map.put(ele.getName(), ele.getText());
                }
            }
        } catch (DocumentException documentException) {
            logger.error("解析报文失败", documentException);
        }
        return map;
    }

    /**
     * docToString
     */
    public static String docToString(Document document) {
        String string = "";
        try {
            ByteArrayOutputStream out = new ByteArrayOutputStream();

            OutputFormat format = new OutputFormat("  ", true, "UTF-8");
            XMLWriter writer = new XMLWriter(out, format);
            writer.write(document);
            string = out.toString("UTF-8");
        } catch (Exception ex) {
            logger.error("docToString error:" + ex.getMessage());
        }
        return string;
    }

    /**
     * stringToDocument
     */
    public static Document stringToDocument(String string) {
        Document doc = null;
        try {
            doc = DocumentHelper.parseText(string);
        } catch (Exception ex) {
            logger.error("stringToDocument error:" + ex.getMessage());
        }
        return doc;
    }

    /**
     * docToXmlFile
     */
    public static boolean docToXmlFile(Document document, String filename) {
        boolean flag = true;
        try {
            OutputFormat format = OutputFormat.createPrettyPrint();
            format.setEncoding("UTF-8");
            XMLWriter writer = new XMLWriter(new FileWriter(new File(filename)), format);
            writer.write(document);
            writer.close();
        } catch (Exception ex) {
            flag = false;
            logger.error("docToXmlFile error:" + ex.getMessage());
        }
        return flag;
    }

    /**
     * stringToXmlFile
     */
    public static boolean stringToXmlFile(String str, String filename) {
        boolean flag = true;
        try {
            Document doc = DocumentHelper.parseText(str);
            flag = docToXmlFile(doc, filename);
        } catch (Exception ex) {
            flag = false;
            logger.error("stringToXmlFile error:" + ex.getMessage());
        }
        return flag;
    }

    /**
     * load
     *
     * @param filename String
     * @return Document
     */
    public static Document load(String filename) {
        Document document = null;
        try {
            SAXReader saxReader = new SAXReader();
            saxReader.setEncoding("UTF-8");
            document = saxReader.read(new File(filename));
        } catch (Exception ex) {
            logger.error("load XML File error:" + ex.getMessage());
        }
        return document;
    }

    /**
     * load
     *
     * @param is InputStream
     * @return Document
     */
    public static Document load(InputStream is) {
        Document document = null;
        try {
            SAXReader saxReader = new SAXReader();
            saxReader.setEncoding("UTF-8");
            document = saxReader.read(is);
        } catch (Exception ex) {
            logger.error("load XML File error:" + ex.getMessage());
        }
        return document;
    }

    /**
     * load
     *
     * @param is     InputStream
     * @param encode String
     * @return Document
     */
    public static Document load(InputStream is, String encode) {
        Document document = null;
        try {
            SAXReader saxReader = new SAXReader();
            saxReader.setEncoding(encode);
            document = saxReader.read(is);
        } catch (Exception ex) {
            logger.error("load XML File error:" + ex.getMessage());
        }
        return document;
    }

    /**
     * styleDocument
     *
     * @param document   Document
     * @param stylesheet String
     * @return Document
     */
    public static Document styleDocument(Document document, String stylesheet) throws Exception {
        TransformerFactory factory = TransformerFactory.newInstance();
        Transformer transformer = factory.newTransformer(new StreamSource(stylesheet));

        DocumentSource source = new DocumentSource(document);
        DocumentResult result = new DocumentResult();
        transformer.transform(source, result);

        Document transformedDoc = result.getDocument();
        return transformedDoc;
    }

}
